/**
 * 参数项接口
 */
export interface ParamItem {
  key: string;
  value: string;
  enabled: boolean;
}

/**
 * 扩展的网络请求详情，包含请求头
 */
interface ExtendedWebRequestDetails extends chrome.webRequest.WebRequestDetails {
  requestHeaders?: chrome.webRequest.HttpHeader[];
}

/**
 * HTTP方法枚举
 */
export enum HttpMethod {
  GET = 'GET',
  POST = 'POST',
  PUT = 'PUT',
  DELETE = 'DELETE',
  PATCH = 'PATCH',
  HEAD = 'HEAD',
  OPTIONS = 'OPTIONS'
}

/**
 * 请求体类型枚举
 */
export enum BodyType {
  NONE = 'none',
  FORM_DATA = 'form-data',
  URLENCODED = 'x-www-form-urlencoded',
  RAW = 'raw',
  BINARY = 'binary'
}

/**
 * 请求模型接口
 */
export interface RequestModel {
  id?: string;
  name?: string;
  url: string;
  method: HttpMethod;
  params: ParamItem[];
  headers: ParamItem[];
  bodyType: BodyType;
  body?: string | ParamItem[] | File;
  rawFormat?: string;
  createdAt?: string | Date;
}

/**
 * 请求模型类
 */
export class Request implements RequestModel {
  id?: string;
  name?: string;
  url: string;
  method: HttpMethod;
  params: ParamItem[];
  headers: ParamItem[];
  bodyType: BodyType;
  body?: string | ParamItem[] | File;
  rawFormat?: string;
  createdAt: Date;

  /**
   * 构造函数
   * @param data 请求数据
   */
  constructor(data: Partial<RequestModel> = {}) {
    console.log('构造Request对象，原始数据:', data);
    
    // 提供所有字段的默认值
    this.id = data.id || crypto.randomUUID();
    this.name = data.name || '';
    this.url = data.url || '';
    this.method = data.method || HttpMethod.GET;
    this.params = Array.isArray(data.params) ? data.params : [];
    this.headers = Array.isArray(data.headers) ? data.headers : [];
    this.bodyType = data.bodyType || BodyType.NONE;
    this.body = data.body;
    this.rawFormat = data.rawFormat || 'json';
    
    // 处理日期，确保是Date对象
    if (data.createdAt) {
      if (typeof data.createdAt === 'string') {
        this.createdAt = new Date(data.createdAt);
      } else {
        this.createdAt = data.createdAt;
      }
    } else {
      this.createdAt = new Date();
    }
    
    console.log('构造Request对象完成:', this);
  }

  /**
   * 获取完整URL（包括参数）
   * @returns 完整URL
   */
  getFullUrl(): string {
    if (!this.url) return '';
    
    const enabledParams = this.params.filter(param => param.enabled);
    if (enabledParams.length === 0) return this.url;
    
    const urlObj = new URL(this.url);
    enabledParams.forEach(param => {
      urlObj.searchParams.append(param.key, param.value);
    });
    
    return urlObj.toString();
  }

  /**
   * 创建请求选项
   * @returns 请求选项
   */
  createRequestOptions(): RequestInit {
    const options: RequestInit = {
      method: this.method,
      headers: {}
    };

    // 添加请求头
    const enabledHeaders = this.headers.filter(header => header.enabled);
    const headerRecord: Record<string, string> = {};
    enabledHeaders.forEach(header => {
      headerRecord[header.key] = header.value;
    });
    options.headers = headerRecord;

    // 根据请求体类型设置请求体
    if (this.method !== HttpMethod.GET && this.method !== HttpMethod.HEAD) {
      switch (this.bodyType) {
        case BodyType.FORM_DATA:
          if (Array.isArray(this.body)) {
            const formData = new FormData();
            (this.body as ParamItem[]).filter(item => item.enabled).forEach(item => {
              formData.append(item.key, item.value);
            });
            options.body = formData;
          }
          break;
        case BodyType.URLENCODED:
          if (Array.isArray(this.body)) {
            const params = new URLSearchParams();
            (this.body as ParamItem[]).filter(item => item.enabled).forEach(item => {
              params.append(item.key, item.value);
            });
            options.body = params;
            headerRecord['Content-Type'] = 'application/x-www-form-urlencoded';
          }
          break;
        case BodyType.RAW:
          if (typeof this.body === 'string') {
            options.body = this.body;
            headerRecord['Content-Type'] = 'application/json';
          }
          break;
        case BodyType.BINARY:
          if (this.body instanceof File) {
            options.body = this.body;
          }
          break;
      }
    }

    return options;
  }

  /**
   * 从网络请求创建请求对象
   * @param request 网络请求
   * @returns 请求对象
   */
  static fromNetworkRequest(request: chrome.webRequest.WebRequestDetails | ExtendedWebRequestDetails): Request {
    try {
      console.log('从网络请求创建Request对象:', request);
      
      if (!request || !request.url) {
        console.warn('网络请求对象无效，创建空Request');
        return new Request();
      }
      
      const url = new URL(request.url);
      const params: ParamItem[] = [];
      
      // 解析URL参数
      url.searchParams.forEach((value, key) => {
        params.push({
          key,
          value,
          enabled: true
        });
      });
      
      // 处理请求头
      const headers: ParamItem[] = [];
      const extendedRequest = request as ExtendedWebRequestDetails;
      if (extendedRequest.requestHeaders) {
        extendedRequest.requestHeaders.forEach((header: chrome.webRequest.HttpHeader) => {
          if (header.name && header.value !== undefined) {
            headers.push({
              key: header.name,
              value: header.value.toString(),
              enabled: true
            });
          }
        });
      }
      
      // 创建请求对象
      return new Request({
        url: `${url.origin}${url.pathname}`,
        method: request.method as HttpMethod,
        params,
        headers,
        bodyType: BodyType.NONE,
        createdAt: new Date(request.timeStamp || Date.now())
      });
    } catch (e) {
      console.error('从网络请求创建Request对象时出错:', e);
      return new Request();
    }
  }

  /**
   * 克隆请求对象
   * @returns 克隆的请求对象
   */
  clone(): Request {
    try {
      console.log('克隆请求对象:', this);
      
      // 安全克隆参数和请求头
      const clonedParams = Array.isArray(this.params) 
        ? this.params.map(param => ({
            key: param.key || '',
            value: param.value || '',
            enabled: Boolean(param.enabled)
          }))
        : [];
        
      const clonedHeaders = Array.isArray(this.headers) 
        ? this.headers.map(header => ({
            key: header.key || '',
            value: header.value || '',
            enabled: Boolean(header.enabled)
          }))
        : [];
      
      // 安全克隆请求体
      let clonedBody: any;
      if (this.body instanceof File) {
        // 文件不能克隆，设为null
        clonedBody = null;
      } else if (Array.isArray(this.body)) {
        // 克隆数组，确保结构正确
        clonedBody = this.body.map(item => {
          if (typeof item === 'object' && item !== null) {
            // 确保是ParamItem结构
            return {
              key: item.key || '',
              value: item.value || '',
              enabled: Boolean(item.enabled)
            };
          }
          return {key: '', value: String(item), enabled: true};
        });
      } else if (typeof this.body === 'object' && this.body !== null) {
        // 将对象转换为字符串，防止对象结构复杂导致问题
        try {
          clonedBody = JSON.stringify(this.body);
        } catch (e) {
          console.warn('请求体序列化失败，设置为空字符串', e);
          clonedBody = '';
        }
      } else if (typeof this.body === 'string') {
        // 字符串直接复制
        clonedBody = this.body;
      } else if (this.body === undefined || this.body === null) {
        // undefined/null处理
        clonedBody = null;
      } else {
        // 其他类型转为字符串
        clonedBody = String(this.body);
      }
      
      return new Request({
        id: crypto.randomUUID(),
        name: this.name || '',
        url: this.url || '',
        method: this.method || HttpMethod.GET,
        params: clonedParams,
        headers: clonedHeaders,
        bodyType: this.bodyType || BodyType.NONE,
        body: clonedBody,
        rawFormat: this.rawFormat || 'json',
        createdAt: new Date()
      });
    } catch (error) {
      console.error('克隆请求对象时出错:', error);
      // 返回一个基本的请求对象，避免完全失败
      return new Request({
        url: this.url || '',
        method: this.method || HttpMethod.GET
      });
    }
  }

  /**
   * 序列化为JSON
   */
  toJSON(): Record<string, any> {
    // 安全处理请求参数和请求头
    const safeParams = Array.isArray(this.params) 
      ? this.params.map(p => this.safeSerializeObject(p))
      : [];
      
    const safeHeaders = Array.isArray(this.headers) 
      ? this.headers.map(h => this.safeSerializeObject(h))
      : [];
      
    // 安全处理请求体
    let safeBody: any = null;
    if (this.body instanceof File) {
      // 文件对象无法序列化，暂时存为null
      safeBody = null;
    } else if (Array.isArray(this.body)) {
      // 处理数组类型的请求体（form-data或urlencoded）
      safeBody = this.body.map(item => this.safeSerializeObject(item));
    } else if (typeof this.body === 'object' && this.body !== null) {
      // 处理对象类型的请求体
      safeBody = this.safeSerializeObject(this.body);
    } else {
      // 其他类型（如字符串）
      safeBody = this.body;
    }
    
    return {
      id: this.id || crypto.randomUUID(),
      name: this.name || '',
      url: this.url || '',
      method: this.method || HttpMethod.GET,
      params: safeParams,
      headers: safeHeaders,
      bodyType: this.bodyType || BodyType.NONE,
      body: safeBody,
      rawFormat: this.rawFormat || 'json',
      createdAt: this.createdAt ? this.createdAt.toISOString() : new Date().toISOString()
    };
  }
  
  /**
   * 安全序列化对象，避免JSON序列化错误
   * @param obj 要序列化的对象
   * @returns 安全的对象
   */
  private safeSerializeObject(obj: any): any {
    if (obj === undefined) return null;
    if (obj === null) return null;
    
    // 处理简单类型
    if (typeof obj !== 'object') return obj;
    
    // 处理Date类型
    if (obj instanceof Date) return obj.toISOString();
    
    // 处理数组
    if (Array.isArray(obj)) {
      return obj.map(item => this.safeSerializeObject(item));
    }
    
    // 处理普通对象
    const result: Record<string, any> = {};
    for (const [key, value] of Object.entries(obj)) {
      // 跳过函数和undefined值
      if (typeof value === 'function' || value === undefined) continue;
      
      // 递归处理嵌套对象
      result[key] = this.safeSerializeObject(value);
    }
    
    return result;
  }
} 